import 'dart:convert';
import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:package_info/package_info.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:zootix/models/zt_app_bottom_nav_item.dart';
import 'package:zootix/models/zt_app_config.dart';
import 'package:zootix/models/zt_oss_policy.model.dart';
import 'package:zootix/screens/follow_conversation/zt_follow_conversation_container.dart';
import 'package:zootix/screens/home/zt_home.dart';
import 'package:zootix/screens/mine/zt_mine.dart';
import 'package:zootix/screens/park/zt_park.dart';
import 'package:zootix/apis/zt-api.dart' as Api;
import 'package:zootix/services/zt_service.dart';
import 'package:zootix/store/zt_auth.store.dart';
import 'package:zootix/util/zt_convert.dart';
import 'package:zootix/util/zt_logger_util.dart';
import 'dart:ui' as ui;
import 'package:device_info_plus/device_info_plus.dart';
import 'package:zootix/zt_config.dart';
import '../constants/zt_constants.dart';

import 'package:app_tracking_transparency/app_tracking_transparency.dart';

class ZtAppInfoService extends GetxService {
  static ZtAppInfoService get to => Get.find();
  final versionNumber = RxString('');
  late AppConfig appConfig;
  late OssPolicy ossPolicy;
  final scale = RxDouble(1.0);
  final isLarge = RxBool(false);
  final isCameraing = RxBool(false);
  IosDeviceInfo? iosDeviceInfo;
  AndroidDeviceInfo? androidDeviceInfo;
  List<AppBottomNavItem>? bottomNavItems = [
    AppBottomNavItem(
        icon: 'assets/images/landing_icon_bottom_0.png',
        activeIcon: 'assets/images/landing_icon_bottom_active_0.png',
        label: 'homepage',
        page: HomePage()),
    AppBottomNavItem(
        icon: 'assets/images/landing_icon_bottom_1.png',
        activeIcon: 'assets/images/landing_icon_bottom_active_1.png',
        label: 'park',
        page: ParkPage()),
    AppBottomNavItem(
        icon: 'assets/images/landing_icon_bottom_2.png',
        activeIcon: 'assets/images/landing_icon_bottom_active_2.png',
        label: 'messageAndfollow',
        page: const ZtFollowConversationContainerPage()),
    AppBottomNavItem(
        icon: 'assets/images/landing_icon_bottom_3.png',
        activeIcon: 'assets/images/landing_icon_bottom_active_3.png',
        label: 'mine',
        page: MinePage()),
  ];
  Future<ZtAppInfoService> init() async {
    ZtLoggerUtil()
        .info("[service-appInfo] Register app-related information service");

    try {
      await Future.wait(
          [getDeviceInfo(), getPackageInfo(), getAppConfig(), getossPolicy()]);
      requestPermission();
    } catch (e) {
      ZtLoggerUtil().error(e);
    }
    return this;
  }

  Future<void> setIsFirstInstall() async {
    await ZtStorageService.to
        .setBool(ZtCacheKeys.isFirstInstall, true, isWithUser: false);
  }

  bool checkIsFirstInstall() {
    bool? isFirstInstallCache = ZtStorageService.to
        .getBool(ZtCacheKeys.isFirstInstall, isWithUser: false);
    return isFirstInstallCache == null || !isFirstInstallCache;
  }

  Future<void> getDeviceInfo() async {
    DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
    if (Platform.isIOS) {
      iosDeviceInfo = await deviceInfo.iosInfo;
      if (iosDeviceInfo != null) {
        await ZtStorageService.to.setString(
            ZtCacheKeys.deviceUUID, iosDeviceInfo!.identifierForVendor!,
            isWithUser: false);
        await ZtStorageService.to.setString(
            ZtCacheKeys.deviceModel, iosDeviceInfo!.name,
            isWithUser: false);
      }
    }
  }

  Future<void> getPackageInfo() async {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    versionNumber.value = packageInfo.version;
    await ZtStorageService.to
        .setString(ZtCacheKeys.ver, packageInfo.version, isWithUser: false);
    await ZtStorageService.to.setString(
        ZtCacheKeys.pVer, packageInfo.buildNumber,
        isWithUser: false);
    await ZtStorageService.to.setString(
        ZtCacheKeys.packageName, packageInfo.packageName,
        isWithUser: false);
  }

  Future<void> getAppConfig() async {
    if (ZtStorageService.to.getString(ZtCacheKeys.token, isWithUser: false) !=
        null) {
      final response = await Api.getAppConfig();
      if (response.data != null) {
        appConfig = AppConfig.fromJson(response.data['data']);
        await ZtStorageService.to.setString(
            ZtCacheKeys.appConfig, jsonEncode(appConfig.items!),
            isWithUser: false);
        // if (appConfig.ver != null) {
        //   await ZtStorageService.to
        //       .setString(ZtCacheKeys.ver, appConfig.ver!, isWithUser: false);
        // }
      }
    }
  }

  // need token
  Future<void> getossPolicy() async {
    if (ZtStorageService.to.getString(ZtCacheKeys.token, isWithUser: false) !=
        null) {
      final response = await Api.getOssPolicy();
      if (response.data != null) {
        ossPolicy = OssPolicy.fromJson(response.data['data']);
      }
    }
  }

  T getConfigByCode<T>(String code) {
    List<AppConfigItem> items = appConfig.items!;
    dynamic config = items.firstWhereOrNull((element) => element.name == code);
    if (config != null) {
      return config.data as T;
    }
    return '' as T;
  }

  void changeTextScale(bool? value) {
    if (value ?? false) {
      scale(1.2);
    } else {
      scale(1.0);
    }
    isLarge.value = value ?? false;
  }

  Future<void> requestPermission() async {
    final status = await AppTrackingTransparency.trackingAuthorizationStatus;
    if (status != TrackingStatus.authorized) {
      await Future.delayed(const Duration(seconds: 2));
      await AppTrackingTransparency.requestTrackingAuthorization();
    }
  }
}
